package com.ican.action.product;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.ican.common.BusinessException;
import com.ican.common.SystemConstants;
import com.ican.common.hibernate.Page;
import com.ican.domain.product.Category;
import com.ican.domain.product.Language;
import com.ican.domain.product.Product;
import com.ican.domain.product.ProductAttribute;
import com.ican.domain.product.ProductImage;
import com.ican.domain.rule.ParseRule;
import com.ican.nc.ParseRuleVo;
import com.ican.nc.ParseUtil;
import com.ican.nc.RuleProductDetailScan;
import com.ican.oc.datasyn.OcDataSynService;
import com.ican.service.product.ProductService;
import com.ican.service.rule.RuleConfigService;
import com.ican.util.ContextUtils;
import com.ican.util.DateUtils;
import com.opensymphony.xwork2.ActionSupport;

public class ProductAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(ProductAction.class);
    
    private ProductService productService;
    private OcDataSynService ocDataSynService;
    private RuleConfigService ruleConfigService;
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    
    private List<Language> langs;
    private Category category;
    private Page<Category> categoryPage = new Page<Category>();
    private Product product;
    private Page<Product> productPage = new Page<Product>();
    private String imgCenterHttp = ParseUtil.getImgCenterHttp();
    private Integer ncStatus;
    
    public String categoryList() {
        langs = productService.findLanguage();
        categoryPage = productService.findAllCategory(categoryPage, category);
        return "cates";
    }

    public String productList() {
        langs = productService.findLanguage();
        productPage = productService.findAllProduct(productPage, product);
        return "list";
    }
    
    public String productInfo() {
        langs = productService.findLanguage();
        product = productService.findProduct(product.getId());
        List<ProductAttribute> attrs = productService.findProductAttrByProductId(product.getId());
        if(attrs == null){
            attrs = new ArrayList<ProductAttribute>();
        }
        product.setAttrs(attrs);
        product.setCategory(productService.findCategory(product.getCategoryId()));
        List<ProductImage> imgs = productService.findProductImageByProductId(product.getId());
        if(imgs == null){
            imgs = new ArrayList<ProductImage>();
        }
        product.setImages(imgs);
        return "info";
    }
    
    public void startCategoryNc() {
        category = productService.findCategory(category.getId());
        if(category.getNcStatus() != null && category.getNcStatus() == SystemConstants.NC_STATUS_RUN){//是否正在运行
            ContextUtils.write2Response("采集任务正在运行中！");
            return;
        }
        if(category.getNcTime() != null && DateUtils.hoursBetweenTwoDate(new Date(), category.getNcTime()) <= 4){//4个小时内只能运行一次
            if(ncStatus == null || ncStatus != SystemConstants.NC_STATUS_FAILED){
                ContextUtils.write2Response("4个小时内只能运行采集一次！");
                return;
            }
        }
        ParseRule rule = ruleConfigService.findRule(category.getRuleId());
        ParseRuleVo ruleVo = new ParseRuleVo();
        ParseUtil.rule2RuleVo(rule, ruleVo);
        try{
            productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_RUN);
            List<Integer> productIds = productService.getAllProductIdForNcByCategory(category.getId(), ncStatus);
            boolean bo = true;
            if(productIds != null){
                for(Integer pid : productIds){
                    try{
                        threadPoolTaskExecutor.execute(new RuleProductDetailScan(pid, ruleVo));
                    }catch(Exception e){
                        bo = false;
                        break;
                    }
                }
            }
            if(bo){
                productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_SUCCESS);
                ContextUtils.write2Response("OK");
            }else{
                productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_FAILED);
                ContextUtils.write2Response("采集任务不能全部启动，超过最大采集数！");
            }
        }catch(Exception e){
            logger.error(e.getMessage(),e);
            productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_FAILED);
            ContextUtils.write2Response(e.getMessage());
        }
    }
    
    public void startProductNc() {
        try{
            ParseRule rule = ruleConfigService.findRule(product.getRuleId());
            ParseRuleVo ruleVo = new ParseRuleVo();
            ParseUtil.rule2RuleVo(rule, ruleVo);
            threadPoolTaskExecutor.execute(new RuleProductDetailScan(product.getId(), ruleVo));
            ContextUtils.write2Response("OK");
        }catch(Exception e){
            logger.error(e.getMessage(),e);
            ContextUtils.write2Response(e.getMessage());
        }
    }
    
    public void startCategorySyn() {
        try{
            int flag = ocDataSynService.synCategory(category.getId(), false);
            if(SystemConstants.ENTITY_DATE_SYN_STATUS_SUCCESS == flag){
                ocDataSynService.synProductByCategory(category.getId(), false);
                ContextUtils.write2Response("OK");
            }else{
                ContextUtils.write2Response("类目同步失败或者正在同步中！");
            }
        }catch(BusinessException e){
            logger.error(e.getMessage(),e);
            ContextUtils.write2Response(e.getMessage());
        }catch(Exception e){
            logger.error(e.getMessage(),e);
            ContextUtils.write2Response(e.getMessage());
        }
    }
    
    public void startProductSyn() {
        try{
            ocDataSynService.synProduct(product.getId(), false);
            ContextUtils.write2Response("OK");
        }catch(BusinessException e){
            logger.error(e.getMessage(),e);
            ContextUtils.write2Response(e.getMessage());
        }catch(Exception e){
            logger.error(e.getMessage(),e);
            ContextUtils.write2Response(e.getMessage());
        }
    }
    
    @Resource
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
    @Resource
    public void setOcDataSynService(OcDataSynService ocDataSynService) {
        this.ocDataSynService = ocDataSynService;
    }
    @Resource
    public void setRuleConfigService(RuleConfigService ruleConfigService) {
        this.ruleConfigService = ruleConfigService;
    }
    @Resource
    public void setThreadPoolTaskExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
    }
    
    public List<Language> getLangs() {
        return langs;
    }
    public void setLangs(List<Language> langs) {
        this.langs = langs;
    }
    public Category getCategory() {
        return category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
    public Page<Category> getCategoryPage() {
        return categoryPage;
    }
    public void setCategoryPage(Page<Category> categoryPage) {
        this.categoryPage = categoryPage;
    }
    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }
    public Page<Product> getProductPage() {
        return productPage;
    }
    public void setProductPage(Page<Product> productPage) {
        this.productPage = productPage;
    }
    public String getImgCenterHttp() {
        return imgCenterHttp;
    }
    public void setImgCenterHttp(String imgCenterHttp) {
        this.imgCenterHttp = imgCenterHttp;
    }

    public Integer getNcStatus() {
        return ncStatus;
    }

    public void setNcStatus(Integer ncStatus) {
        this.ncStatus = ncStatus;
    }
}
